﻿using S7.Net;
using ScannerSuccessRate.Helper;
using ScannerSuccessRate.Model;
using ScannerSuccessRate.PLC;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ScannerSuccessRate
{
    public partial class FrmMain : Form
    {

        public static FrmMain mainFormInstance;

        public static Action<string> action;

        public FrmMain()
        {
            InitializeComponent();
            mainFormInstance = this;
        }

        // 定义一个标识确保线程同步
        public static readonly object locker = new object();
        public static MyPlc PLC;
        public static string PLCIp = "";
        static Task mainTask = null;
        static bool isRunning = true;
        static SqlSugarScope db = null;
        string scannerIp = null;
        public static FrmMain GetInstance()
        {
            if (mainFormInstance == null)
{
                lock (locker)
                {
                    if (mainFormInstance == null)
                    {
                        mainFormInstance = new FrmMain();
                    }
                }
            }
            return mainFormInstance;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            db = SqlHelper.GetSqlInstance();
            isRunning = true;
            ConnectPLCTimer.Interval = 1000;
            ConnectPLCTimer.Start();
            ReadPLCTimer.Interval = 1000;
            ReadPLCTimer.Start();
        }

        /// <summary>
        /// 主界面加载完成之后，连接PLC
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_Shown(object sender, EventArgs e)
        {
            ConnectToPlc();
        }

        /// <summary>
        /// PLC连接状态看门狗
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ConnectPLCTimer_Tick(object sender, EventArgs e)
        {
            // WCS连接PLC状态的监测方法
            PLC_Connect_WatchDog();
        }

        private void ReadPLCTimer_Tick(object sender, EventArgs e)
        {
            readInStorageScannerPort(sender);
        }


        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            isRunning = false;
        }


        /// <summary>
        /// 连接PLC
        /// </summary>
        public void ConnectToPlc()
        {
            PLCIp = ConfigurationManager.ConnectionStrings["PLC_IP"].ConnectionString;
            var inputIP = PLC_TextBox.Text;
            if (inputIP != null && inputIP.Length >= 15)
            {
                PLCIp = inputIP;
            }
            scannerIp = "192.168.56.10";
            string text = Scanner_TextBox.Text;
            if (text.Length >= 15)
            {
                scannerIp = text;
            }

            if (PLC == null)
            {
                PLC = new MyPlc(CpuType.S71500, PLCIp, 0, 1);
                PLC.Open();
            }
        }


        private void stop_Click(object sender, EventArgs e)
        {
            isRunning = false;
        }

        private void start_Click(object sender, EventArgs e)
        {
            isRunning = true;
        }

        /// <summary>
        /// 入库扫码点,DB16
        /// </summary>
        public static ConcurrentDictionary<string, InStorageScannerPortRead> InStorageScannerPortDict = new ConcurrentDictionary<string, InStorageScannerPortRead>();

        /// <summary>
        ///  读入库扫码点,DB16
        /// </summary>
        public void readInStorageScannerPort(object sender)
        {
            InStorageScannerPortRead model = new InStorageScannerPortRead();
            if (PLC.IsConnected)
            {
                int v = PLC.ReadClass(model, 16, 0);
                if(isRunning && model.ReadInPlaceComplete == 1)
                {
                    // 到达入库扫码点
                    string code = ScannerHelper.read(scannerIp, 5025);
                    if (code == "Noread")
                    {
                        for (int i = 0; i < 5; i++){
                            code = ScannerHelper.read(scannerIp, 5025);
                            if (code != "Noread")
                            {
                                break;
                            }
                        }
                    }
                    var entity = new ScannerModel();
                    entity.code = code;
                    entity.time = DateTime.Now;
                    entity.ip = scannerIp;
                    this.listBox1.Items.Add("扫码器IP:"+scannerIp + ",扫到条码"+code);
                    ScannerModel backRes = db.Insertable(entity).ExecuteReturnEntity();
                    this.listBox1.Items.Add("插入扫码数据:"+ backRes);
                }
            }
        }

        public T AddOrUpdateGenerics<T>(ConcurrentDictionary<string, T> container, string key, T newValue)
        {
            bool v = container.TryGetValue(key, out T oldValue);
            if (oldValue != null)
            {
                bool v1 = container.TryRemove(key, out oldValue);
                bool v2 = container.TryAdd(key, newValue);
            }
            else
            {
                container.TryAdd(key, newValue);
            }
            return newValue;
        }


        private short heartBeat = 0;
        /// <summary>
        ///  PLC连接状态看门狗，PLC断开连接之后，自动重连
        /// </summary>
        public void PLC_Connect_WatchDog()
        {
            // 下发心跳，判断PLC连接状态
            if (heartBeat == 0)
            {
                heartBeat = 1;
            }
            else
            {
                heartBeat = 0;
            }
            try
            {
                // 下发心跳数据
                PLC.Write(DataType.DataBlock, Convert.ToInt16(22), Convert.ToInt16(56), heartBeat);
            }
            catch
            {
                try
                {
                    if (PLC != null && !PLC.IsConnected)
                    {
                        PLC = new MyPlc(CpuType.S71500, PLCIp, 0, 1);
                        PLC.Open();
                    }
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        
    }
}
